package com.tvunetworks.center.user.service.impl;

import com.tvunetworks.center.common.exception.ServerException;
import com.tvunetworks.center.common.util.EndecryptUtil;
import com.tvunetworks.center.user.mapper.InstancePeerIdMapper;
import com.tvunetworks.center.user.model.InstancePeerId;
import com.tvunetworks.center.user.model.UserInstance;
import com.tvunetworks.center.user.model.param.InstanceIdWithPeerId;
import com.tvunetworks.center.user.model.result.ResultConstant;
import com.tvunetworks.center.user.service.InstancePeerIdService;
import com.tvunetworks.center.user.service.UserInstanceService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @program: tvucc-aggregator
 * @description: InstancePeerIdServiceImpl
 * @author lebronchen
 * @create: 2020-04-23 16:27
 **/
@Service
@Slf4j
public class InstancePeerIdServiceImpl extends BaseService<InstancePeerId> implements InstancePeerIdService {

    @Autowired
    private InstancePeerIdMapper instancePeerIdMapper;
    @Autowired
    private UserInstanceService userInstanceService;

    @Value("${instance.cloudR.domainPrefix}")
    private String domainPrefix;
    @Value("${instance.cloudR.domain}")
    private String cloudDomain;
    @Value("${instance.cloudR.webR.suffix}")
    private String cloudWebRSuffix;
    @Value("${instance.cloudR.webR.port}")
    private String cloudWebRPort;
    @Value("${instance.cloudR.webR.useDomain}")
    private boolean webRUseDomain;
    @Value("${aliyun.domain.split:_}")
    private String aliyunDomainSplit;
    @Value("${instance.cloudR.domainSuffix:T1279}")
    private String domainSuffix;

    @Override
    @Transactional
    public void addInstancePeerId(String userInstanceId, List<String> peerIds) {
        if (CollectionUtils.isEmpty(peerIds)) {
            log.error("addInstancePeerId failed, peerIds is null userInstanceId:{}", userInstanceId);
            return;
        }
        for (String peerId : peerIds) {
            InstancePeerId record = new InstancePeerId()
                    .setUserInstanceId(userInstanceId)
                    .setPeerId(peerId);
            super.insert(record);
            log.error("addInstancePeerId success userInstanceId:{} peerId:{}", userInstanceId, peerId);
        }
    }

    @Override
    public List<String> listPeerIdByUserInstanceId(String userInstanceId) {
        return instancePeerIdMapper.listPeerIdByUserInstanceId(userInstanceId);
    }

    @Override
    public String getWebRUrl(InstanceIdWithPeerId param) {
        String instanceId = param.getInstanceId();
        String peerId = param.getPeerId();

        UserInstance userInstance = userInstanceService.getByInstanceId(instanceId);
        if (userInstance == null) {
            throw new ServerException(ResultConstant.UserInstance.NOT_EXIST);
        }

        if (!(UserInstance.STATUS_RUNNING == userInstance.getStatus())) {
            throw new ServerException(ResultConstant.UserInstance.ALREADY_CLOSED);
        }

        List<String> peerIds = this.listPeerIdByUserInstanceId(userInstance.getId());
        if (!peerIds.contains(peerId)) {
            throw new ServerException(ResultConstant.UserInstance.INVALID_PEER_ID);
        }
        int i = 0;
        for (; i < peerIds.size(); i++) {
            if (peerId.equalsIgnoreCase(peerIds.get(i))) {
                break;
            }
        }

        List<String> ports = Stream.of(cloudWebRPort.split(",")).collect(Collectors.toList());

        StringBuilder url = new StringBuilder();
        if (webRUseDomain) {
            StringBuilder sb = new StringBuilder();
            if (StringUtils.isNotBlank(domainPrefix)) {
                sb.append(domainPrefix).append(aliyunDomainSplit);
            }
            sb.append(peerId.toUpperCase()).append(domainSuffix);
            String domain = EndecryptUtil.MD5(sb.toString());
            url.append(domain).append(".").append(cloudDomain);
        } else {
            url.append(userInstance.getPublicIp());
        }
        url.append(":").append(ports.get(i)).append(cloudWebRSuffix);

        return url.toString();
    }
}
